/**
 * 
 */
package com.yuejie.urlparse;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * @author leilz
 * @date 2012-6-28
 */
public class UrlParser {
	private Logger logger = Logger.getLogger(UrlParser.class);
	/**
	 * <p>获取返回的json</p>
	 * @param requestUrl
	 * @return
	 */
	public String getJsonStr(String requestUrl){
		URL url = null;
		HttpURLConnection conn = null;
		BufferedReader br = null;
		String s = "";
		StringBuffer sb = new StringBuffer("");
		
		try {
			url = new URL(requestUrl);
			conn = (HttpURLConnection) url.openConnection();
			conn.setInstanceFollowRedirects(false);
			conn.connect();
			int httpStatus = conn.getResponseCode();
			if(httpStatus != HttpURLConnection.HTTP_OK){
				logger.warn(requestUrl + ":状态码-"+httpStatus);
			}else{
				br = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
				while ((s = br.readLine()) != null) {
					sb.append(s+"\r\n");
				}
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			logger.warn("打开给定url连接失败,url=" + requestUrl);
			e.printStackTrace();
		}
		String responseStr = sb.toString();
		responseStr = responseStr.substring(0,responseStr.lastIndexOf("\r\n"));
		return responseStr;
	}
	
	/**
	 * <p>获取真实视频地址</p>
	 * @param seed
	 * @param objFields
	 * @param objSegs
	 * @param sid
	 * @param format
	 * @return
	 * @throws JSONException
	 */
	public String[] getRealUrl(double seed,JSONObject objFields,JSONObject objSegs,String sid,String format) throws JSONException{
		String[] realUrl = null;
		String fileId = "";
		if(format.equals("hd2")){
			try{
				fileId = objFields.getString("hd2");
			} catch (JSONException e1){
				return new String[]{};
			}
		}else if(format.equals("mp4")){
			try{
				fileId = objFields.getString("mp4");
			} catch (JSONException e1){
				return new String[]{};
			}
		}else{
			try{
				fileId = objFields.getString("flv");
			} catch (JSONException e1){
				return new String[]{};
			}
		}
		
		String realFileid = getRealFieldID(fileId, seed);
		
		String fieldIdLeft = realFileid.substring(0, 8);
		String fieldIdRight = realFileid.substring(10);
		
		JSONArray formatArray = objSegs.getJSONArray(format);
		realUrl = new String[formatArray.length()];
		if(format.equals("hd2")){
			format = "flv";
		}
		for (int i = 0; i < formatArray.length(); i++){
			JSONObject o = formatArray.getJSONObject(i);
			String k = o.getString("k");
			realUrl[i] = "http://f.youku.com/player/getFlvPath/sid/" + sid + "_" + String.format("%1$02X", i) + "/st/" + format
					+ "/fileid/" + fieldIdLeft + String.format("%1$02X", i) + fieldIdRight + "?K=" + k;
		}
		
		return realUrl;
	}
	
	/**
	 * <p>获取全部真实视频地址,普通、高清、超清</p>
	 * @param jsonStr
	 * @return
	 * @throws JSONException
	 */
	public List<String[]> getRealUrlList(String requestUrl) throws JSONException{
		String vid = requestUrl.substring(requestUrl.indexOf("id_")+3, requestUrl.indexOf(".html"));
		String reqJsonUrl = "http://v.youku.com/player/getPlayList/VideoIDS/" + vid;
		String jsonStr = getJsonStr(reqJsonUrl);
		
		List<String[]> realUrlList = new LinkedList<String[]>();
		JSONObject jsonObj = new JSONObject(jsonStr);
		JSONArray jsonArray = jsonObj.getJSONArray("data");
		JSONObject objTop = jsonArray.getJSONObject(0);
		
		double seed = objTop.getDouble("seed");
		JSONObject objFields = objTop.getJSONObject("streamfileids");
		JSONObject objSegs = objTop.getJSONObject("segs");
		
		String sid = generateSid();
		
		String[] flvStrArray = getRealUrl(seed,objFields,objSegs,sid,"flv");
		String[] mp4StrArray = getRealUrl(seed,objFields,objSegs,sid,"mp4");
		String[] hd2StrArray = getRealUrl(seed,objFields,objSegs,sid,"hd2");
		realUrlList.add(flvStrArray);
		realUrlList.add(mp4StrArray);
		realUrlList.add(hd2StrArray);
		
		return realUrlList;
	}

	/**
	 * <p>生成sid</p>
	 * @return
	 */
	public String generateSid() {
		int i1 = (int) (1000 + Math.floor(Math.random() * 999));
		int i2 = (int) (1000 + Math.floor(Math.random() * 9000));
		return System.currentTimeMillis() + "" + i1 + "" + i2;
	}

	public String getRealFieldID(String fileId, double seed) {
		String mixed = getFieldIDMixString(seed);
		String[] ids = fileId.split("\\*");
		StringBuilder realId = new StringBuilder();
		int idx;
		for (int i = 0; i < ids.length; i++) {
			idx = Integer.parseInt(ids[i]);
			realId.append(mixed.charAt(idx));
		}
		return realId.toString();
	}

	public String getFieldIDMixString(double seed) {
		StringBuilder mixed = new StringBuilder();
		StringBuilder source = new StringBuilder("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890");
		int index, len = source.length();
		for (int i = 0; i < len; ++i) {
			seed = (seed * 211 + 30031) % 65536;
			index = (int) Math.floor(seed / 65536 * source.length());
			mixed.append(source.charAt(index));
			source.deleteCharAt(index);
		}
		return mixed.toString();
	}

}
